/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.core.http.impl;

import cn.hutool.core.util.StrUtil;
import info.peigen.hotpot.component.gateway.core.exception.GatewayBusinessException;
import info.peigen.hotpot.component.gateway.core.http.HttpClient;
import info.peigen.hotpot.component.gateway.core.http.enums.HttpType;
import info.peigen.hotpot.component.gateway.core.http.request.HttpRequest;
import info.peigen.hotpot.component.gateway.core.http.ssl.SslSocketHttpClientBase;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.noear.solon.annotation.Component;

import java.net.SocketTimeoutException;
import java.nio.charset.Charset;

/**
 * <b>(FormHttpClient)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021-07-06
 */
@Slf4j
@Component
public class FormHttpClient extends SslSocketHttpClientBase implements HttpClient {

    @Override
    public String send(HttpRequest request) throws Exception {
        switch (request.getMethodType()) {
            case GET:
                return doGet(request);
            case POST:
                return doPost(request);
            default:
                log.warn("请求异常：没找到正确的请求方式[默认POST]，HttpRequest={}", request);
                return null;
        }

    }

    private String doGet(HttpRequest req) throws Exception {

        OkHttpClient client = initClient(req);

        Request.Builder requestBuild = new Request.Builder();
        requestBuild.addHeader("accept", "*/*");
        requestBuild.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        requestBuild.addHeader("connection", "Keep-Alive");
        HttpUrl.Builder urlBuilder = HttpUrl.parse(req.getRequestUrl()).newBuilder();

        if (req.getRequestMessageMap() != null && !req.getRequestMessageMap().isEmpty()) {
            req.getRequestMessageMap().entrySet()
                    .stream().filter(param -> StrUtil.isNotEmpty(param.getValue()))
                    .forEach(param -> urlBuilder.addQueryParameter(param.getKey(), param.getValue()));
        }

        requestBuild.url(urlBuilder.build());

        try (Response response = client.newCall(requestBuild.build()).execute()) {
            return response.body().string();
        } catch (Exception e) {
            log.error("get请求发生错误", e);

            if (e instanceof SocketTimeoutException) {
                throw e;
            }
            throw new GatewayBusinessException(e.getMessage(), e.getCause());
        }

    }

    private String doPost(HttpRequest req) throws Exception {
        OkHttpClient client = initClient(req);

        FormBody.Builder formBodyBuilder = new FormBody.Builder(Charset.defaultCharset());

        if (req.getRequestMessageMap() != null && !req.getRequestMessageMap().isEmpty()) {
            req.getRequestMessageMap().entrySet()
                    .stream().filter(param -> StrUtil.isNotEmpty(param.getValue()))
                    .forEach(param -> formBodyBuilder.add(param.getKey(), param.getValue()));
        }

        RequestBody formBody = formBodyBuilder.build();

        Request request = new Request.Builder()
                .url(req.getRequestUrl())
                .post(formBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (Exception e) {
            log.error("post请求发生错误", e);

            if (e instanceof SocketTimeoutException) {
                throw e;
            }

            throw new GatewayBusinessException(e.getMessage(), e.getCause());
        }
    }

    @Override
    public HttpType httpType() {
        return HttpType.FORM;
    }
}